package com.cci.kangdao.utilTool;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.apache.commons.collections4.MapUtils;
import org.apache.log4j.Logger;

import java.util.Date;
import java.util.Map;
import java.util.UUID;

/**
 * @author William Du
 * @date 2020/11/9
 */
public class TokenUtils {

    private static Logger log = Logger.getLogger(TokenUtils.class);

    private static final Long SEED = 194432L;
    private static final Long CTY_SEED = 234491L;
    private static final String ISSUER = "cummins";
    private static final String SUBJECT = "cty-eCummins";
    private static final String CLAIM_NAME = "claim";
    private static final String CLAIM_VALUE = "cty";

    /**
     * CTY生成Token，供EW系统校验使用
     * @return token CTY生成的Token
     */
    public static String getToken() {
        Date  now = new Date();
        String currentDay = LocalTimeUtil.getFormatterTime(now,"yyyyMMdd");
        long dayReverse = Long.parseLong(new StringBuilder(currentDay).reverse().toString());
        Long expireTimestamp = now.getTime() + 1000 * 60 * 10L;
        Date expireDate = new Date(expireTimestamp);
        Long merge = dayReverse + CTY_SEED;
        String secretKey = String.format("cty%d@eCummins", merge);
        Algorithm algorithm = Algorithm.HMAC256(secretKey);
        String token = JWT.create()
                .withIssuer(ISSUER)
                .withSubject(SUBJECT)
                .withClaim(CLAIM_NAME, CLAIM_VALUE)
                .withExpiresAt(expireDate)
                .sign(algorithm);
        return token;
    }

    /**
     * 根据外部传入的参数生成token
     * @param secretKey
     * @param timestamp
     * @return
     */
    public static String getToken(String secretKey,Long timestamp) {
        Date  now = new Date();
        Date expireDate = new Date(now.getTime() + timestamp);
        Algorithm algorithm = Algorithm.HMAC256(secretKey);
        String token = JWT.create()
                .withIssuer(ISSUER)
                .withSubject(SUBJECT)
                .withClaim(CLAIM_NAME, CLAIM_VALUE)
                .withExpiresAt(expireDate)
                .sign(algorithm);
        return token;
    }
    /**
     * 校验EW系统生成的Token是否符合要求
     * @param token EW系统生成的Token
     * @return Boolean 是否校验通过
     */
    public static Boolean validateToken(String token) {
        Boolean validate = Boolean.FALSE;
        try {
            Date  now = new Date();
            String currentDay = LocalTimeUtil.getFormatterTime(now,"yyyyMMdd");
            //String reverseDay = LocalTimeUtil.getFormatterRealCurrentTime("yyyyMMdd");
            long dayReverse = Long.parseLong(new StringBuilder(currentDay).reverse().toString());
            String secretKey = String.format("cty%d@eCummins", SEED + dayReverse);
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(secretKey))
                    .acceptExpiresAt(now.getTime() + 1000 * 60 * 10L)
                    .build();
            DecodedJWT jwt = verifier.verify(token);
            // 判断参数是否符合要求
            Map<String, Claim> claims = jwt.getClaims();
            if (null != MapUtils.getObject(claims, CLAIM_NAME)) {
                Claim claim = MapUtils.getObject(claims, CLAIM_NAME);
                String claimValue = claim.asString();
                // 判断是否过期，并且claim参数是否符合设定
                if (jwt.getExpiresAt().after(now) && CLAIM_VALUE.equals(claimValue)) {
                    validate = Boolean.TRUE;
                }
            }
        } catch (TokenExpiredException e) {
            log.error("JWT Token过期", e);
        } catch (Exception e) {
            log.error("JWT Token验证错误", e);
        }
        return validate;
    }

    public static String getTokenEW() {
        Date  now = new Date();
        String currentDay = LocalTimeUtil.getFormatterTime(now,"yyyyMMdd");
        long dayReverse = Long.parseLong(new StringBuilder(currentDay).reverse().toString());
        Long expireTimestamp = now.getTime() + 1000 * 60 * 10L;
        Date expireDate = new Date(expireTimestamp);
        Long merge = dayReverse + SEED;
        String secretKey = String.format("cty%d@eCummins", merge);
        Algorithm algorithm = Algorithm.HMAC256(secretKey);
        String token = JWT.create()
                .withIssuer(ISSUER)
                .withSubject(SUBJECT)
                .withClaim(CLAIM_NAME, CLAIM_VALUE)
                .withExpiresAt(expireDate)
                .sign(algorithm);
        return token;
    }

    public static String getTempToken(){
        return UUID.randomUUID().toString();
    }

    public static void main(String[] args) {
    }

}
